package ar.com.larreta.comunes;

import java.beans.PropertyDescriptor;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.beanutils.PropertyUtils;

import ar.com.larreta.excepciones.Excepcion;

public class DescriptorDeObjeto extends Objeto {

	private Object origen;
	private Map<String, DescriptorDePropiedad> descriptoresDePropiedades = new HashMap<String, DescriptorDePropiedad>();
	
	protected Transformador transformador;
	
	public DescriptorDeObjeto(Object origen, Transformador transformador) {
		super();
		this.transformador = transformador;
		if (origen != null) {
			this.origen = origen;
			Collection<PropertyDescriptor> propiedades = Arrays.asList(PropertyUtils.getPropertyDescriptors(origen.getClass()));
			Iterator<PropertyDescriptor> it = propiedades.iterator();
			while (it.hasNext()) {
				PropertyDescriptor propertyDescriptor = (PropertyDescriptor) it.next();
				descriptoresDePropiedades.put(propertyDescriptor.getName(),	Descriptores.getInstancia().getDescriptorDePropiedad(origen, propertyDescriptor, transformador));
			}
		} else {
			// FIXME: Lanzar excepcion
		}
	}

	public Object getOrigen() {
		return origen;
	}
	
	public Iterator<DescriptorDePropiedad> iterator() {
		return descriptoresDePropiedades.values().iterator();
	}

	public DescriptorDePropiedad getDescriptor(String nombre) {
		return descriptoresDePropiedades.get(nombre);
	}

	public Boolean esCollection() {
		return Herramientas.esDelTipo(origen.getClass(), Collection.class);
	}

	public void copiar(DescriptorDeObjeto descriptorDestino) {
		try {
			Iterator<DescriptorDePropiedad> descriptores = descriptorDestino.iterator();
			while (descriptores.hasNext()) {
				DescriptorDePropiedad descriptorDePropiedadDestino = (DescriptorDePropiedad) descriptores.next();
				DescriptorDePropiedad descriptorDePropiedadOrigen = getDescriptor(descriptorDePropiedadDestino.getNombre());
				
				if ((descriptorDePropiedadDestino != null)	&& (descriptorDePropiedadOrigen != null)
						&& (descriptorDePropiedadDestino.sePuedeEscribir())	&& (descriptorDePropiedadOrigen.sePuedeLeer())) {
					descriptorDePropiedadDestino.copiar(descriptorDePropiedadOrigen);
				}
			}
		} catch (Exception e) {
			logger.error(Excepcion.getStackTrace(e));
		}
	}
}
